/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = rtcp_comm.c                                        */
/*  NOTE      =                                                    */
/*  DATE      = 2015/07/20 by songbb                               */
/*******************************************************************/

#include <stdio.h>
#include <memory.h>
#include <sys/time.h>

#include "frmem.h"
#include "frlog.h"
#include "frreport_comm.h"
#include "frct_comm.h"
#include "frdb_cursor.h"

#include "rtcp_core.h"
#include "rtcp_comm.h"

static char hex_asc[] = "0123456789abcdef";
#define hex_asc_lo(x)   hex_asc[((x) & 0x0f)]
#define hex_asc_hi(x)   hex_asc[((x) & 0xf0) >> 4]

/*******************************************************************************
*  FUNC     :  释放内存
*  ARGS     :  pp_buffer
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
void rtcp_free(void **pp_buffer)
{
    if (pp_buffer == NULL || *pp_buffer == NULL)
        return;

    frfree(*pp_buffer);
    *pp_buffer = NULL;
    return;
}

/*******************************************************************************
*  FUNC     :  时间格式化成 2015-03-29 22:25:12.448671 的格式
*  ARGS     :  *p_tv                           (时间戳)
*           :  *p_time                         (buffer)
*           :  ui_time_size                    (buffer size)
*  RTN      :
*  NOTE     :
*******************************************************************************/
int rtcp_frtime2datetimestr(struct timeval *p_tv
                        , char *p_time
                        , unsigned int ui_time_size)
{
    struct tm *p_tm = NULL;

    if(p_tv == NULL || p_time == NULL || ui_time_size <= 1)
        return FR_FAIL;

    p_tm = localtime(&(p_tv->tv_sec));

    snprintf(p_time,ui_time_size,"%04d-%02d-%02d %02d:%02d:%02d.%06ld",
             p_tm->tm_year + 1900,p_tm->tm_mon + 1,p_tm->tm_mday,
             p_tm->tm_hour,p_tm->tm_min,p_tm->tm_sec,p_tv->tv_usec);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  打印时间
*  ARGS     :  st_timestamp                         (时间戳)
*  RTN      :
*  NOTE     :
*******************************************************************************/
void rtcp_print_timeval(struct timeval st_timestamp)
{
    char arr_buff[64];
    rtcp_frtime2datetimestr(&st_timestamp, arr_buff, sizeof(arr_buff));
    printf(":[%s]\n", arr_buff);
}

/*******************************************************************************
*  FUNC     :  格式化成十六进制字符串
*  ARGS     :  *p_inbuff    (输入的字符串)
*           :  i_len        (输入的字符串长度)
*           :  *p_outbuff   (格式化后的十六进制字符串)
*  RTN      :
*  NOTE     :
*******************************************************************************/
void rtcp_util_to_hex_string(char *p_inbuff
                            , int i_len
                            , char *p_outbuff)
{
    int i_loop;
    char c;
    int i_used = 0;

    for (i_loop = 0; i_loop < i_len; i_loop++)
    {
        c = p_inbuff[i_loop];
        p_outbuff[i_used++] = hex_asc_hi(c);
        p_outbuff[i_used++] = hex_asc_lo(c);
    }

    return;
}

/*******************************************************************************
*  FUNC     :  按一个字节打印十六进行字符串
*  ARGS     :  *p_buff  (char*字符串)
*           :  i_len   (字符串长度)
*  RTN      :
*  NOTE     :
*******************************************************************************/
void rtcp_print_hex_string(char *p_buff
                        , int i_len)
{
    int i_loop;

    for (i_loop = 0; i_loop < i_len; i_loop++)
        printf("%02x", p_buff[i_loop] & 0xFF);

    return;
}

/*******************************************************************************
*  FUNC     :  打印指定位置的包内容
*  ARGS     :  *p_st_rtcp_packet                     (RTCP数据包)
*           :  i_pos                                (开始位置)
*           :  i_len                                (长度)
*  RTN      :
*  NOTE     :
*******************************************************************************/
void rtcp_print_packet_specified(L7_rtcp_packet *p_st_rtcp_packet
                                , int i_pos
                                , int i_len)
{
    if (p_st_rtcp_packet == NULL)
        return;
    char *p_buff_tmp = NULL;
    if (bytebuff_show(p_st_rtcp_packet->p_st_packet, i_pos, i_len, &p_buff_tmp) != FR_SUCC)
        return;
    rtcp_print_hex_string(p_buff_tmp, i_len);
    rtcp_free((void **) &p_buff_tmp);
    return;
}

/*******************************************************************************
*  FUNC     :  打印当前位置开始的包内容
*  ARGS     :  *p_st_rtcp_packet                     (RTCP数据包)
*  RTN      :
*  NOTE     :
*******************************************************************************/
void rtcp_print_packet_current(L7_rtcp_packet *p_st_rtcp_packet)
{
    if (p_st_rtcp_packet == NULL)
        return;
    char *p_buff_tmp = NULL;
    if (bytebuff_show(p_st_rtcp_packet->p_st_packet, bytebuff_getPosition(p_st_rtcp_packet->p_st_packet), bytebuff_remaining(p_st_rtcp_packet->p_st_packet), &p_buff_tmp) != FR_SUCC)
        return;
    rtcp_print_hex_string(p_buff_tmp, bytebuff_remaining(p_st_rtcp_packet->p_st_packet));
    rtcp_free((void **) &p_buff_tmp);
    return;
}

/*******************************************************************************
*  FUNC     :  打印整个包内容
*  ARGS     :  *p_st_rtcp_packet                     (RTCP数据包)
*  RTN      :
*  NOTE     :
*******************************************************************************/
void rtcp_print_packet(L7_rtcp_packet *p_st_rtcp_packet)
{
    if (p_st_rtcp_packet == NULL)
        return;
    char *p_buff_tmp = NULL;
    if (bytebuff_show(p_st_rtcp_packet->p_st_packet, 0, bytebuff_length(p_st_rtcp_packet->p_st_packet), &p_buff_tmp) != FR_SUCC)
        return;
    rtcp_print_hex_string(p_buff_tmp, bytebuff_length(p_st_rtcp_packet->p_st_packet));
    rtcp_free((void **) &p_buff_tmp);
    return;
}
